package org.shopen.puremvc.model.domain.testing
{
	import mx.collections.ArrayCollection;
	
	import org.shopen.puremvc.model.domain.ISerializable;
	import org.shopen.puremvc.model.utils.Convert;

	public class Test implements ISerializable
	{
		public static const TYPE : String = "simpletest";
		
		[Bindable]
		private var _id : String = "";
		[Bindable]
		public function get id() : String
		{
			return _id;
		}
		public function set id(value : String) : void
		{
			_id = value;
		}
		
		[Bindable]
		private var _points : Number;
		[Bindable]
		public function get points() : Number
		{
			return _points;
		}
		public function set points(value : Number) : void
		{
			_points = value;
		}
		
		[Bindable]
		private var _question : String = "";
		[Bindable]
		public function get question() : String
		{
			return _question;
		}
		public function set question(value : String) : void
		{
			_question = value;
		}
		
		[Bindable]
		private var _options : OptionsCollection;
		[Bindable]
		public function get options() : OptionsCollection
		{
			return _options;
		}
		public function set options(value : OptionsCollection) : void
		{
			_options = value;
		}
		
		public function Test(node : XML = null)
		{
			if (node != null)
			{
				deserialize(node);
			}
		}

		public function deserialize(node:XML):void
		{
			if ("@id" in node)
			{
				this.id = Convert.toString(node.@id);
			}
			if ("@points" in node)
			{
				this.points = Convert.toNumber(node.@points);
			}
			
			if ("question" in node)
			{
				this.question = Convert.stripCDATA(Convert.toString(node.question));
			}
			
			this.options = new OptionsCollection(node);
		}
		
		public function serialize():XML
		{
			// TODO: consider implement if needed.
			// do not forget about @type attr.
			return null;
		}
		
		public virtual function getPoints(userAnswer : ArrayCollection) : Number
		{
			var result : Number = 0;
			var rawPoints : Number = 0;
			var counter : Number = 0;
			for each (var option : Option in options.optionsArray)
			{
				var isCorrect : Boolean = option.checkCorrect(userAnswer.getItemAt(counter));
				rawPoints += isCorrect ? 1 : 0;
				counter++;
			}
			result = rawPoints / counter * points;
			return result;
		}
		
		public virtual function isCorrect(userAnswer : ArrayCollection) : Boolean
		{
			var result : Boolean = getPoints(userAnswer) >= points;
			return result;
		}
		
		public virtual function getType() : String
		{
			return Test.TYPE;
		}
		
		public virtual function clone() : Test
		{
			var result : Test = new Test();
			cloneFileds(result);
			return result;
		}
		
		protected virtual function cloneFileds(object : Test) : void
		{
			object.id = this.id;
			object.options = this.options.clone();
			object.points = this.points;
			object.question = this.question;
		}
	}
}